package com.galaxy.service.service.global.impl;

import com.galaxy.commom.base.exception.RequestException;
import com.galaxy.commom.base.holder.SpringContextHolder;
import com.galaxy.commom.base.message.ResponseCode;
import com.galaxy.commom.base.utils.Collections3;
import com.galaxy.service.entity.system.Permission;
import com.galaxy.service.realm.MyRealm;
import com.galaxy.service.service.global.ShiroService;
import com.galaxy.service.service.system.PermissionService;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * shiro接口
 * @author caijinbang
 * @date 2018/10/28 00:42
 */
@Slf4j
@Service
public class ShiroServiceImpl implements ShiroService {

  @Autowired
  private PermissionService permissionService;

  /**
   * 获取拦截器数据
   * @return
   */
  @Override
  public Map<String, String> getFilterChainDefinitionMap() {

    Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>();
    List<String[]> permsList = new LinkedList<>();
    List<String[]> anonList = new LinkedList<>();
    List<Permission> permissions = permissionService.list();
    if(Collections3.isNotEmpty(permissions)){
      for (Permission permission : permissions) {
        if(!StringUtils.isEmpty(permission.getUrl()) && !StringUtils.isEmpty(permission.getPermission())){
          if(!"".equals(permission.getPermission().trim())) {
            //判断是否需要权限验证
            if(permission.getVerification()){
              permsList.add(0,new String[]{permission.getUrl()+
                  "/**","perms["+permission.getPermission()+":*]"});
            }else{
              anonList.add(0,new String[]{permission.getUrl()+ "/**","anon"});
            }
          }
        }
        iterationAllResourceInToFilter(permission,permsList,anonList);
      }
    }
    for (String[] strings : anonList) {
      filterChainDefinitionMap.put(strings[0],strings[1]);
    }
    for (String[] strings : permsList) {
      filterChainDefinitionMap.put(strings[0],strings[1]);
    }
    filterChainDefinitionMap.put("/**", "anon");
    return filterChainDefinitionMap;
  }

  @Override
  public void iterationAllResourceInToFilter(Permission resource,
      List<String[]> permsList,List<String[]> anonList){
    if(resource.getChildren()!=null && resource.getChildren().size()>0){
      for (Permission v : resource.getChildren()) {
        if(!StringUtils.isEmpty(v.getUrl()) && !StringUtils.isEmpty(v.getPermission())){
          if(v.getVerification()){
            permsList.add(0,new String[]{v.getUrl()+"/**","perms["+v.getPermission()+":*]"});
          }else{
            anonList.add(0,new String[]{v.getUrl()+"/**","anon"});
          }
          iterationAllResourceInToFilter(v,permsList,anonList);
        }
      }
    }
  }

  @Override
  public void reloadPerms() {
    ShiroFilterFactoryBean shiroFilterFactoryBean = SpringContextHolder.getBean(ShiroFilterFactoryBean.class);

    AbstractShiroFilter abstractShiroFilter;
    try {
      abstractShiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean.getObject();
    } catch (Exception e) {
      throw new RequestException(ResponseCode.FAIL.code,"重新加载权限失败",e);
    }
    PathMatchingFilterChainResolver filterChainResolver =
        (PathMatchingFilterChainResolver) abstractShiroFilter.getFilterChainResolver();
    DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver
        .getFilterChainManager();

    //清除旧版权限
    manager.getFilterChains().clear();
    shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();

    //更新新数据
    Map<String, String> filterChainDefinitionMap = getFilterChainDefinitionMap();
    shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
    filterChainDefinitionMap.forEach(manager::createChain);
  }

  /**
   * 根据用户id清空授权信息
   * @param uid 用户ID
   * @param author 是否清空授权信息
   * @param out 是否清空session
   */
  @Override
  public void clearAuthByUserId(String uid,Boolean author, Boolean out){
    MyRealm myRealm = SpringContextHolder.getBean(MyRealm.class);
    myRealm.clearAuthByUserId(uid,author,out);
  }

  /**
   * 根据用户id集合清空授权信息
   * @param userList 用户ID集合
   * @param author 是否清空授权信息
   * @param out 是否清空session
   */
  @Override
  public void clearAuthByUserIdCollection(List<String> userList, Boolean author, Boolean out) {
    MyRealm myRealm = SpringContextHolder.getBean(MyRealm.class);
    myRealm.clearAuthByUserIdCollection(userList,author,out);
  }

}
